package cn.walls1717.wallsmall.seckill.scheduled;

import cn.walls1717.wallsmall.seckill.service.SeckillService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

import static cn.walls1717.wallsmall.seckill.constant.SeckillRedisKeyConstant.UPLOAD_LOCK;

/**
 * 秒杀商品定时上架
 *
 * @author walls1717
 * @since 2022/11/25 16:28
 **/
@Slf4j
@Service
public class SeckillSkuScheduled {
    @Resource
    private SeckillService seckillService;
    @Resource
    private RedissonClient redissonClient;

    /**
     * 在每天凌晨3点，上架今天，明天，后天三天的秒杀商品。<br>
     * 这样会出现一个问题，比如今天有一个秒杀商品要在10点秒杀，但是定时任务却在凌晨3点才会上架今天的秒杀商品，
     * 这个无需担心，因为今天的秒杀商品在前几天就会被定时任务上架。但是这又会出现重复上架问题，通过幂等性处理解决重复上架问题。
     */
    @Scheduled(cron = "0/5 * * * * ?")
    public void uploadSeckillSkuLatest3Days() {
        // 使用分布式锁解决并发上架问题
        RLock lock = redissonClient.getLock(UPLOAD_LOCK);
        lock.lock(10, TimeUnit.SECONDS);
        try {
            seckillService.uploadSeckillSkuLatest3Days();
        } finally {
            lock.unlock();
        }
    }
}
